﻿using HandyControl.Controls;
using Mapster;
using MaterialDesignThemes.Wpf;
using Minotaur.App.Core;
using Minotaur.App.Core.Attributes;
using Minotaur.App.Core.Contrls;
using Minotaur.App.Core.Mvvm;
using Minotaur.App.Core.Redis;
using Minotaur.App.Domains.Dto;
using Minotaur.App.Domains.Model.Menu;
using Minotaur.App.Domains.ViewModel.Menu;
using Minotaur.App.Modules.Business.Service.Mneu;
using Newtonsoft.Json;
using Prism.Commands;
using Prism.Ioc;
using Prism.Modularity;
using Prism.Mvvm;
using Prism.Regions;
using ServiceStack;
using ServiceStack.Text;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using static System.Net.Mime.MediaTypeNames;

namespace Minotaur.App.Modules.SystemSet.ViewModels
{
    public class MenuViewModel : WindowComputeViewModel
    {
        private readonly IMenuInfoListService menuInfoListService;
        private ObservableCollection<MenuInfoListViewModel> _menuInfos = new ObservableCollection<MenuInfoListViewModel>();

        private readonly IContainerProvider containerProvider;
        /// <summary>
        /// 菜单类型
        /// </summary>
        public ObservableCollection<MenuInfoListViewModel> MenuInfos { get => _menuInfos; set => SetProperty(ref _menuInfos, value); }

        public DataGrid MenuTreeGrid { get; set; }



        public MenuViewModel(IRegionManager regionManager, IDbContext dbContext, IRedisClient _redisClient, IMenuInfoListService _menuInfoListService, IContainerProvider containerProvider) : base(regionManager, dbContext, _redisClient)
        {
            this.menuInfoListService = _menuInfoListService;
            this.containerProvider = containerProvider;
        }


        private List<PackIconKindViewModel> _PackIconKinds = new List<PackIconKindViewModel>();

        /// <summary>
        /// 菜单选项
        /// </summary>
        private MenuInfoViewModel _MenuInfo;

        #region 函数注册区域

        /// <summary>
        /// 新增菜单函数
        /// </summary>
        public ICommand AddNewMenuCommand => new DelegateCommand<object>(AddNewMenuAction);

        [GlobalLogAspect]
        private void EditNewMenuAction(object obj)
        {
            long id = (long)obj;
            OpendLoading = true;
            Task.Run(async () =>
            {
                Minotaur.App.Domains.Model.Menu.MenuInfo info = await this.dbContext.BusinessDb.Queryable<MenuInfo>().FirstAsync(o => o.AutoId == id);
                List<MenuRes> res = await this.dbContext.BusinessDb.Queryable<MenuRes>().Where(o => o.MenuId == id).ToListAsync();
                string cnName = res.FirstOrDefault(o => o.Lan == 0)?.Value;
                string enName = res.FirstOrDefault(o => o.Lan == 1)?.Value;
                if (info != null)
                {
                    BussineKeyValueDto icon = null;


                    if (!string.IsNullOrEmpty(info.Icon))
                    {
                        List<BussineKeyValueDto> icons = JsonConvert.DeserializeObject<List<BussineKeyValueDto>>(info.Icon);
                        icon = icons.FirstOrDefault(o => o.Label == "pc");
                    }
                    this.Dispatcher.Invoke(() =>
                    {
                        this.MenuInfo = info.Adapt<MenuInfoViewModel>();
                        if (this.MenuInfo != null)
                        {
                            this.MenuInfo.Name = cnName;
                            this.MenuInfo.EnName = enName;
                            if (icon != null)
                                this.MenuInfo.PackIconKind = this.PackIconKinds.FirstOrDefault(o => o.IconKind.GetHashCode().ToString() == icon.Value);
                        }
                        this.IsRightDrawerOpen = true;
                        OpendLoading = false;
                    });
                }
            });
        }

        /// <summary>
        /// 关闭弹出表单
        /// </summary>
        public ICommand ClosedMenuFormCommand => new DelegateCommand(ClosedMenuFormAction);

        private void ClosedMenuFormAction()
        {
            this.IsRightDrawerOpen = false;
        }

        /// <summary>
        /// 关闭弹出表单
        /// </summary>
        public ICommand SaveMenuFormCommand => new DelegateCommand(SaveMenuFormAction);
        [GlobalLogAspect]
        private void SaveMenuFormAction()
        {

            OpendLoading = true;
            Task.Run(async () =>
            {
                var results = await this.menuInfoListService.SaveMenuInfo(this.MenuInfo);
                List<MenuInfoDto> menuInfoDtos = new List<MenuInfoDto>();
                if (results)
                {
                    menuInfoDtos = await menuInfoListService.GenerateMenuInfo();
                    InitData();
                    this.ShowSuccess = "保存菜单信息成功!";
                }
                this.Dispatcher.Invoke(() =>
                {
                    this.IsRightDrawerOpen = false;
                    if (results)
                    {
                        InitLeftMenu(menuInfoDtos);
                    }
                    else
                    {
                        OpendLoading = false;
                        Growl.Error("保存菜单信息失败!");
                    }
                });
            });
        }


        public List<PackIconKindViewModel> PackIconKinds { get => _PackIconKinds; set => SetProperty(ref _PackIconKinds, value); }
        public MenuInfoViewModel MenuInfo { get => _MenuInfo; set => SetProperty(ref _MenuInfo, value); }

        private void AddNewMenuAction(object obj)
        {
            this.MenuInfo = new MenuInfoViewModel() { ParentCode = obj + "" };
            this.IsRightDrawerOpen = true;
        }

        //protected override void WindowSizeChanged(object sender, SizeChangedEventArgs e)
        //{
        //    //if (this.MenuTreeGrid != null)
        //    //{
        //    //    this.MenuTreeGrid.Height = System.Windows.Application.Current.MainWindow.ActualHeight - 140;
        //    //}
        //    DockPanel dockPanel = this.FormDependencyObject as DockPanel;
        //    if (dockPanel != null)
        //    {
        //        dockPanel.Width = System.Windows.Application.Current.MainWindow.ActualWidth / 2.5;
        //    }
        //}

        public override void InitData()
        {
            Task.Run(() =>
              {
                  var results = this.menuInfoListService.InitMenuInfosAsync().Result;
                  var menus = results.Adapt<ObservableCollection<MenuInfoListViewModel>>();
                  foreach (var item in menus)
                  {
                      item.DeleteAction = DeleteAction;
                      item.NewAction = AddNewMenuAction;
                      item.EditAction = EditNewMenuAction;
                      item.PropertyChanged += ItemPropertyChanged;
                      item.CreatorName = GetEmpCache(item.Creator.ToInt());
                      if (!item.Childs.Any())
                      {
                          item.IsVisible = Visibility.Hidden;
                      }
                  }
                  List<PackIconKindViewModel> pcakKinds = new List<PackIconKindViewModel>();
                  for (int i = 5000; i <= 5050; i++)
                  {
                      if (!pcakKinds.Any(o => ((int)o.IconKind) == i))
                      {
                          PackIconKind packIconKind = (PackIconKind)i;
                          pcakKinds.Add(new PackIconKindViewModel() { IconKind = packIconKind, Name = packIconKind.ToString() });
                      }
                  }
                  this.Dispatcher.Invoke(() =>
                  {
                      base.InitBtnEnabel();
                      this.PackIconKinds = pcakKinds.Distinct().ToList();
                      this.MenuInfos = menus;
                      OpendLoading = false;
                  });
              });
        }


        public void ItemPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            if (e.PropertyName.ToLower() == "ischecked")
            {
                OpendLoading = true;
                Task.Run(() =>
                {
                    var selectedObj = sender as MenuInfoListViewModel;
                    if (selectedObj == null || !selectedObj.Childs.Any())
                    {
                        OpendLoading = false;
                        return;
                    }
                    if (selectedObj.IsChecked)
                    {
                        int next = MenuInfos.IndexOf(selectedObj) + 1;
                        for (int i = 0; i < selectedObj.Childs.Count; i++)
                        {
                            var p = selectedObj.Childs[i];
                            if (!p.Childs.Any())
                            {
                                p.IsVisible = Visibility.Hidden;
                            }
                            p.MarginLeft = selectedObj.MarginLeft + 16;
                            p.PropertyChanged += ItemPropertyChanged;
                            p.IsChecked = false;
                            p.CreatorName = GetEmpCache(p.Creator.ToInt());
                            p.DeleteAction = DeleteAction;
                            p.NewAction = AddNewMenuAction;
                            p.EditAction = EditNewMenuAction;
                            this.Dispatcher.Invoke(() =>
                            {
                                this.MenuInfos.Insert(next++, p);
                            });
                        }
                        this.Dispatcher.Invoke(() =>
                        {
                            OpendLoading = false;
                        });
                    }
                    else if (!selectedObj.IsChecked)
                    {
                        for (int i = 0; i < selectedObj.Childs.Count; i++)
                        {
                            var p = selectedObj.Childs[i];
                            RemoveNode(p);
                        }
                    }
                });
            }
        }

        private void RemoveNode(MenuInfoListViewModel person)
        {
            for (int i = 0; i < person.Childs.Count; i++)
            {
                var p = person.Childs[i];
                RemoveNode(p);
            }
            for (int i = 0; i < MenuInfos.Count; i++)
            {
                var p = MenuInfos[i];
                if (p.Code == person.Code)
                {
                    this.Dispatcher.Invoke(() =>
                    {
                        MenuInfos.Remove(p);
                    });
                }
            }
            this.Dispatcher.Invoke(() =>
            {
                OpendLoading = false;
            });
        }
        [GlobalLogAspect]
        public void DeleteAction(object obj)
        {

            OpendLoading = true;
            Task.Run(() =>
            {
                var results = true;
                MenuInfoListViewModel viewModel = (MenuInfoListViewModel)obj;
                bool status = viewModel.Status.HasValue ? !viewModel.Status.Value : false;
                var dbResult = this.dbContext.BusinessDb.UseSugarTranAsync(async () =>
                {
                    await this.dbContext.BusinessDb.Updateable<MenuInfo>()
                    .SetColumns(o => o.Status == status)
                    .Where(o => o.AutoId == viewModel.AutoId)
                    .ExecuteCommandAsync();
                    return true;
                }).Result;
                results = dbResult.IsSuccess;
                List<MenuInfoDto> menuInfoDtos = new List<MenuInfoDto>();
                if (results)
                {
                    menuInfoDtos = menuInfoListService.GenerateMenuInfo().Result;
                    this.ShowSuccess = status ? "启用菜单信息成功!" : "禁用菜单信息成功!";
                    InitData();
                }
                this.Dispatcher.Invoke(() =>
                {
                    this.IsRightDrawerOpen = false;
                    if (results)
                    {
                        InitLeftMenu(menuInfoDtos);
                    }
                    else
                    {
                        OpendLoading = false;
                        Growl.Error(status ? "启用菜单信息失败!" : "禁用菜单信息失败!");
                    }
                });
            });
        }
        void InitLeftMenu(List<MenuInfoDto> menuInfoDtos)
        {
            Minotaur.App.Modules.SystemControl.Views.SideMenu sideMenu = CoordinateUilts.GetChildObjects<Minotaur.App.Modules.SystemControl.Views.SideMenu>(System.Windows.Application.Current.MainWindow).FirstOrDefault(o => o.Name == "menuInfo");
            if (sideMenu != null)
            {
                sideMenu.ItemsSource = null;
                sideMenu.OpendMenuClick -= OpendMenuClick;
                sideMenu.ItemsSource = menuInfoDtos;
                sideMenu.OpendMenuClick += OpendMenuClick;
                AppDataContext.GlobalUserModel.MenuInfos = menuInfoDtos;
            }
        }

        private void OpendMenuClick(object sender, RoutedEventArgs e)
        {
            MenuInfoDto menuInfo = e.OriginalSource as MenuInfoDto;

            if (menuInfo != null && (menuInfo.Childs is null || !menuInfo.Childs.Any()))
            {
                containerProvider.Resolve<IModuleManager>().LoadModule(menuInfo.ModuleCode);
                IModuleManager moduleManager = containerProvider.Resolve<IModuleManager>();
                if (moduleManager.ModuleExists(menuInfo.ModuleCode) && GlobalConst.Views.Any(o => o == menuInfo?.Code))
                {
                    moduleManager.LoadModule(menuInfo.ModuleCode);
                    RegionManager?.RequestNavigate(RegionNames.ContentRegion, menuInfo?.Code);
                }
                else
                {
                    moduleManager.LoadModule("system");
                    RegionManager?.RequestNavigate(RegionNames.ContentRegion, "404");
                }
            }
        }
        #endregion
    }
}
